// 对local，session，cookie，websql，indexeddb封装
export default {
  session: {
    set(key: string, data?: any) {
      sessionStorage.setItem(key, JSON.stringify(data));
    },
    get(key: string) {
      if (!isJSONParse(sessionStorage.getItem(key))) {
        return sessionStorage.getItem(key);
      }
      return JSON.parse(sessionStorage.getItem(key) as string);
    },
    remove(key: string) {
      sessionStorage.removeItem(key);
    },
    clear() {
      sessionStorage.clear();
    },
  },
  local: {
    set(key: string, data?: any) {
      localStorage.setItem(key, JSON.stringify(data));
    },
    get(key: string) {
      if (!isJSONParse(localStorage.getItem(key))) {
        return localStorage.getItem(key);
      }
      return JSON.parse(localStorage.getItem(key) as string);
    },
    remove(key: string) {
      localStorage.removeItem(key);
    },
    clear() {
      localStorage.clear();
    },
  },
  cookie: {
    set(key: string, value: string, seconds: number) {
      let d: any = new Date();
      d.setTime(d.getTime() + seconds * 1000);
      const expires = "expires=" + d.toGMTString();
      document.cookie = key + "=" + value + "; " + expires;
    },
    get(key: string) {
      const array = document.cookie?.split(";");
      for (let i = 0; i < array.length; i++) {
        const new_Array = array[i]?.split("=");
        const n_key = new_Array[0]?.replace(/^\s/, "");
        if (n_key == key) {
          return new_Array[1];
        }
      }
      return "";
    },
    remove(key: any) {
      this.set(key, "", -1);
    },
    clear() {
      const keys = document.cookie.match(/[^ =;]+(?=\=)/g);
      if (keys) {
        for (let i = keys.length; i--; )
          document.cookie = keys[i] + "=0;expires=" + new Date(0).toUTCString();
      }
    },
  },
  websql: {
    db: null,
    databaseName: "数据库名",
    version: "1.0.0",
    describe: "数据库相关描述",
    databaseSize: 2 * 1024 * 1024,
    connect() {
      this.db = (window as any).openDatabase(
        this.databaseName,
        this.version,
        this.describe,
        this.databaseSize
      );
    },
    defOption: {
      param: [],
      success: function () {},
      error: function () {},
    },
    execute(option: any) {
      if (option.hasOwnProperty("sql")) {
        option.param = option.param || this.defOption.param;
        option.success = option.success || this.defOption.success;
        option.error = option.error || this.defOption.error;
        if (!this.db) this.connect();

        (this.db as any).transaction(function (tx: any) {
          tx.executeSql(
            option.sql,
            option.param,
            function (transaction: any, result: any) {
              option.success(transaction, result);
            },
            function (transaction: any) {
              option.error(transaction);
            }
          );
        });
      }
    },
    createTable({ tName, tHead }: any) {
      this.execute({
        sql: `CREATE TABLE IF NOT EXISTS ${tName} (id integer primary key AutoIncrement, ${tHead.join(
          ","
        )})`,
      });
    },
    add(params: any) {
      const tName = params.tName;
      const keys = Object.keys(params.data);
      const values = Object.values(params.data);
      this.execute({
        sql: `INSERT INTO ${tName} (${keys.join(",")}) VALUES (${Array(
          keys.length
        )
          .fill("?")
          .join(",")})`,
        param: values,
        success: function (transaction: any, result: any) {
          console.log("数据写入成功");
        },
        error(transaction: any) {
          console.log("数据写入失败");
        },
      });
    },
    query(params: any) {
      const tName = params.tName;
      this.execute({
        sql: `SELECT * FROM ${tName}`,
        success: function (transaction: any, result: any) {
          params.success && params.success(result.rows);
        },
      });
    },
    queryDataById(params: any) {
      this.execute({
        sql: `SELECT * FROM ${params.tName} WHERE id = ${params.id}`,
        success: function (transaction: any, result: any) {
          params.success && params.success(result.rows);
        },
      });
    },
    updateDataById(params: any) {
      const tName = params.tName;
      const id = params.id;
      const keys = Object.keys(params.data);
      const values = Object.values(params.data);
      let str = "";
      keys.forEach((key) => {
        str += key + "=?";
      });

      this.execute({
        sql: `UPDATE ${tName} SET ${str} WHERE id = ${id}`,
        param: values,
        success: function () {
          params.success && params.success("update success");
        },
      });
    },
    delDataByIDById(params: any) {
      const tName = params.tName;
      const id = params.id;
      this.execute({
        sql: `DELETE FROM ${tName} WHERE id = ${id}`,
        param: [],
        success: function () {
          params.success && params.success("delete success");
        },
      });
    },
    dropTableByName(params: any) {
      const tName = params.tName;
      this.execute({
        sql: `DROP TABLE ${tName}`,
        param: [],
        success: function () {
          params.success && params.success("drop table success");
        },
      });
    },
    dropDbByName(params: any) {
      const dbName = params.dbName;
      this.execute({
        sql: `DROP DATABASE [IF EXISTS] ${dbName}`,
        param: [],
        success: function () {
          params.success && params.success("drop db success");
        },
      });
    },
  },
  indexedDB: {
    IDBName: "数据库名",
    version: 1,
    indexName: "idIndex",
    indexFieldKey: "id",
    active: null,
    IDB:
      window.indexedDB ||
      (window as any).mozIndexedDB ||
      (window as any).webkitIndexedDB ||
      (window as any).msIndexDB,
    openDB(params: any) {
      return new Promise((resolve: any, reject: any) => {
        const request = this.IDB.open(this.IDBName, this.version);
        request.onupgradeneeded = (event: any) => {
          this.active = event.target.result;
          this.createdDB(params);
        };
        request.onsuccess = (event: any) => {
          this.active = request.result as any;
          resolve();
        };
        request.onerror = () => {
          reject();
          console.log("数据库出错");
        };
      });
    },
    async createdDB(params: any) {
      if (!this.active) await this.openDB(params);
      const tName = params.tName;
      if (!(this.active as any).objectStoreNames.contains(tName)) {
        const objectDb = (this.active as any).createObjectStore(tName, {
          keyPath: "id",
          autoIncrement: true,
        });
        objectDb.createIndex(this.indexName, this.indexFieldKey, {
          unique: true,
        });
      }
    },
    async add(params: any) {
      if (!this.active) await this.openDB(params);
      const data = params.data;
      const tName = params.tName;
      return new Promise((resolve, reject) => {
        const request = (this.active as any)
          .transaction([tName], "readwrite")
          .objectStore(tName)
          .add(data);
        request.onsuccess = (event: any) => {
          resolve("数据写入成功");
        };
        request.onerror = (event: any) => {
          reject("数据写入失败");
        };
      });
    },
    async query(params: any) {
      if (!this.active) await this.openDB(params);
      const tName = params.tName;
      return new Promise((resolve, reject) => {
        const request = (this.active as any)
          .transaction(tName, "readwrite")
          .objectStore(tName)
          .getAll();
        request.onsuccess = () => {
          resolve(request.result);
        };
      });
    },
    async queryDataById(params: any) {
      if (!this.active) await this.openDB(params);
      const tName = params.tName;
      const id = params.id;
      return new Promise((resolve, reject) => {
        const transaction = (this.active as any).transaction(
          [tName],
          "readwrite"
        );
        const objectStore = transaction.objectStore(tName);
        const request = objectStore.get(id);
        request.onerror = (event: any) => {
          reject(event);
        };
        request.onsuccess = (event: any) => {
          if (request.result) {
            resolve(request.result);
          } else {
            reject(event);
          }
        };
      });
    },
    async update(params: any) {
      if (!this.active) await this.openDB(params);
      const tName = params.tName;
      const data = params.data;
      return new Promise((resolve, reject) => {
        const request = (this.active as any)
          .transaction([tName], "readwrite")
          .objectStore(tName)
          .put(data);

        request.onsuccess = (event: any) => {
          resolve("数据更新成功");
        };

        request.onerror = (event: any) => {
          reject("数据更新失败");
        };
      });
    },
    async delDataByIDById(params: any) {
      if (!this.active) await this.openDB(params);
      const id = params.id;
      const tName = params.tName;
      return new Promise((resolve: any, reject: any) => {
        const request = (this.active as any)
          .transaction([tName], "readwrite")
          .objectStore(tName)
          .delete(id);
        request.onsuccess = (event: any) => {
          resolve();
          console.log("数据删除成功");
        };
      });
    },
    async clear(params: any) {
      if (!this.active) await this.openDB(params);
      const tName = params.tName;
      return new Promise((resolve: any, reject: any) => {
        const request = (this.active as any)
          .transaction([tName], "readwrite")
          .objectStore(tName)
          .clear();
        request.onsuccess = (event: any) => {
          resolve("数据清空成功");
        };
      });
    },
    async queryDataByIndex(params: any) {
      if (!this.active) await this.openDB(params);
      const tName = params.tName;
      const indexName = params.indexName;
      const indexFieldValue = params.indexFieldValue;
      return new Promise((resolve: any, reject: any) => {
        const transaction = (this.active as any).transaction(
          [tName],
          "readonly"
        );
        const store = transaction.objectStore(tName);
        const index = store.index(indexName);
        const request = index.get(indexFieldValue);

        request.onsuccess = function (e: any) {
          const result = e.target.result;
          resolve(result);
        };
      });
    },
  },
  clearAll(callback) {
    return new Promise((resolve: any, reject: any) => {
      this.session.clear();
      this.local.clear();
      this.cookie.clear();
      callback && callback();
      resolve();
    });
  },
};
